package servidor1;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import principal.*;

import Obrero.Obrero;
import cliente.Cliente;

public class Servidor implements Runnable{

    private ServerSocket ss;  
    private Thread hilos = new Thread(this);
    private Socket sc;
    private int contador =0;

    private Obrero obreroreceptor=null;

    private PrincipalView principal; //este es un objeto principal
    private boolean buclerecibir;
    private boolean bucleaccept;

    public Servidor(Integer puerto, PrincipalView p) // pasar como parametro el principal que viene del main
    {
        principal = p;
            try
            {
                    ss = new ServerSocket(puerto);// crea socket servidor que escuchara el puerto "puerto"
                    ss.setSoTimeout(1000);
            }		
            catch(Exception e )
            {
                    System.out.println("ErrorA: "+e.getMessage());
            }

            hilos.start(); //se inicia el hilo del servidor
    }

    public void stop()
    {
            hilos.stop();
    }



    @Override
    public void run()
    {
        buclerecibir = true;
        bucleaccept = true;
        boolean conexionEstablecida = false;
        int segundos = 0;
        
        System.out.println("Servidor: Esperando una conexion.");

        while(bucleaccept){
            try 
            {
                System.out.println("Servidor: " + segundos + "'' esperando una conexion.");
                sc = ss.accept();
                System.out.println("Servidor: Conexión establecida.");
                conexionEstablecida = true;
                bucleaccept = false;
                principal.ServidorIniciado(); //se avisa al principal que se ha establecido una conexion
            }
            catch(SocketTimeoutException t){
                segundos++;
                conexionEstablecida = false;
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

        while(buclerecibir&&conexionEstablecida)
        {
            servidor_recibir(); //el servidor se queda escuchando nuevos mensajes que vengan del cliente
        }
        
        try {
            ss.close();
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
        System.out.println("Conexión terminada: Hilo servidor finalizado.");
    }

    public synchronized void enviar_dato(Obrero objeto)  throws  IOException {
       
       
        String metodo = "envio" + objeto.getname();
        principal.EjecutarMetodoServidorIniciado(metodo);
        try {

            ObjectOutputStream oos;
            try {
                    oos = new ObjectOutputStream(sc.getOutputStream());
            }catch(IOException ex ){
                    javax.swing.JOptionPane.showMessageDialog(null, "Se perdió la conexión.");
                    System.exit(0);
                    return;
            }

            oos.writeObject(objeto);
            oos.flush();
            contador++;    
            System.out.println(contador+"-termino obrero: "+ objeto.getname());
                    //System.out.println("obrero_servidor: " + objeto.getname());
                    //System.out.println("Estado_servidor: " + objeto.getEstado());

        } catch (UnknownHostException ex) {
            Logger.getLogger(cliente.Cliente.class.getName()).log(Level.SEVERE, null, ex);
        } 
        ss.close();
    }



    public void servidor_recibir()//recibir un objeto en el servidor
    {
            try {

            ObjectInputStream ois;
            try {
                    ois = new ObjectInputStream(sc.getInputStream());
            }catch(IOException ex ){
                    buclerecibir = false;
                    return;
            }

            try {
                obreroreceptor =(Obrero) ois.readObject(); 
                if (obreroreceptor!=null)
                {

                //ACA SE DEBEN LLAMAR LOS METODOS QUE INICIEN los obreros en el server
                //que hayan sidos recibidos desde el cliente
                System.out.println("recibi un obrero en el servidor: ");
                System.out.println("obrero_recibido_servidor: " +obreroreceptor.getname());
                System.out.println("estado_recibido_servidor: " +obreroreceptor.getEstado());
                        if ("FINCONEXION".equals(obreroreceptor.getname()))
                        {
                            terminarrun();
                        }	
                obreroreceptor=null; //lo borro provisoriamente para recibir nuevos obreros
                                                                    //en la misma variable...
                }

                }
                catch (ClassNotFoundException ex) 
                {
                    Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.println("Error class ");}

                    // ois.close();
                    // sc.close();


            } catch (UnknownHostException ex) {
                    System.out.println("Error host ");
                    Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            System.out.println("Error IO ");
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                    System.out.println("Error General ");
                    Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
            }

    }


    public void salir() //se cierran los sockets SOLO INVOCAR AL FINALIZAR EL PROGRAMA!!!
    {
        if(sc.isClosed()) System.out.println("Servidor esta cerrado.");
            try{ 
                    sc.close();
                    ss.close();
            }
            catch(IOException e)
            {
            System.out.println("ErrorD: "+e.getMessage());
            System.exit(0);
            }
            System.out.println("Conexion finalizada");
    }

    public void terminarrun()
    {
        buclerecibir=false;
    }

    public void cancelar(){
        bucleaccept = false;
    }

}